package net.helix.ui.panels.library;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.GraphicsDevice;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Timer;
import java.util.TimerTask;

import net.helix.engine.Engine;
import net.helix.engine.library.LibraryTreeNode;
import net.helix.engine.library.items.LibraryItem;
import net.helix.engine.library.items.LibraryItem_Image;
import net.helix.engine.library.items.LibraryItem.LibraryItemType;
import net.helix.graphics.GraphicsEngine;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.AWTGLCanvas;
import org.lwjgl.opengl.Drawable;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.PixelFormat;


public class LibraryPreview extends AWTGLCanvas implements FocusListener, DragGestureListener, DragSourceListener {
	private static final long serialVersionUID = 1L;
	
	private int changeCount = 0;
	
	private static final int TransitionLength = 3;
	
	Timer t;
	
	LibraryPane libraryPane;
	Engine engine;
	public LibraryPreview(Engine engine, LibraryPane _libraryPane, GraphicsDevice gd, PixelFormat pf, Drawable drawable) throws LWJGLException {
		super(gd, pf, drawable);
		this.engine = engine;
		this.libraryPane = _libraryPane;
		
		this.addComponentListener(this);
		this.addFocusListener(this);
		
		this.setFocusable(true);
		
		t = new Timer();
		
		final DragSource ds = DragSource.getDefaultDragSource();
		ds.createDefaultDragGestureRecognizer((Component) this, DnDConstants.ACTION_COPY_OR_MOVE, this);
		
		//final LibraryPreview This = this;
		
		addMouseListener(new MouseAdapter(){
			@Override
			public void mousePressed(MouseEvent e) {
				
				/*
				System.out.println("mousePressed");
				
				LibraryPreviewTransferHandler handler = (LibraryPreviewTransferHandler) libraryPane.getLibraryPreviewParentPanel().getTransferHandler();
				
				Transferable transferable = handler.createTransferable(currentNode);
				//handler.exportAsDrag((JComponent) e.getSource(), e, TransferHandler.COPY);
				
				//DropTarget dt = new DropTarget();
				//dt = new DropTarget(This, DnDConstants.ACTION_COPY_OR_MOVE, null);
				ds.createDefaultDragGestureRecognizer((Component) This, DnDConstants.ACTION_COPY_OR_MOVE, This);
				
				;
				
				
				DragGestureEvent g = 
				new DragGestureEvent(
					       new DragGestureRecognizer(new DragSource(), This) {
							private static final long serialVersionUID = 1L;

							@Override
							protected void registerListeners() {
								// TODO Auto-generated method stub
								
							}

							@Override
							protected void unregisterListeners() {
								// TODO Auto-generated method stub
								
							}

					}, DnDConstants.ACTION_COPY, new Point(0,0), This.ge);
				
				ds.startDrag(g, null, transferable, This);
				/*
				LibraryTreeTransferHandler handler = new LibraryTreeTransferHandler(libraryPane.getTreeTableModel());
				handler.createTransferableFromPreview((JComponent)libraryPane.getTreeTable(), currentItem);
				handler.exportAsDrag(libraryPane.getTreeTable(), e, TransferHandler.COPY);
				*/
			}
		});
		
		
	}
	public LibraryItem currentItem = null;
	public LibraryTreeNode currentNode = null;
	public void changePreviewPicTo(LibraryTreeNode node){
		if(node == null){
			currentNode = null;
			currentItem = null;
			changeCount = 0;
			
			repaint();
		}else{
			LibraryItem item = engine.getCurrentSelectedLibrary().getItem(node.id);
			if(currentItem != item){
				currentNode = node;
				
				currentItem = item;
				
				changeCount = 0;
				
				repaint();
			}
		}
	}
	@Override
	public void initGL(){
		super.initGL();
		
		GL11.glViewport(0, 0, getWidth(), getHeight());
		
		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		
		//GL11.glFrustum(0, 1, 0, 1, 1, -1);
		//GL11.glOrtho(0, 1, 0, 1, 1, -1);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
		GL11.glLoadIdentity();
	}
	
	private Runnable runOnceFunction;
	
	public void setRunOnceFunction(Runnable toRun){
		runOnceFunction = toRun;
	}
	
	@Override
	public void paintGL() {
		super.paintGL();
		
		if(runOnceFunction != null){
			runOnceFunction.run();
			runOnceFunction = null;
		}
		
		changeCount++;
		
		GraphicsEngine.rebindRequired();
		
		try {
			GL11.glClearColor(1, 1, 1, 0);
			
			GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
			
			GL11.glViewport(0, 0, getWidth(), getHeight());
			
			if(currentItem != null){
				
					LibraryItem item = (LibraryItem) currentItem;
					
					//Transform transform = new Transform(TransformDimension.TWO);
					//transform.setScale(1/item.getWidth(), 1/item.getHeight(), 1);
					
					//GL11.glPushMatrix();
					//transform.apply();
					
					GL11.glMatrixMode(GL11.GL_PROJECTION);
					GL11.glLoadIdentity();
					
					GL11.glMatrixMode(GL11.GL_MODELVIEW);
					GL11.glLoadIdentity();
					
					System.out.println("Should render:");
					item.renderLibrary(engine, getWidth(), getHeight());
					//item.render(1, 1, 1, (float)changeCount/(float)TransitionLength);
					
					//GL11.glPopMatrix();
					
				
				
			}
			swapBuffers();
		} catch (LWJGLException e) {
			e.printStackTrace();
		}
		if(changeCount <= TransitionLength){
			t.schedule(new redrawIt(), 16);
		}
	}
	public void componentResized(ComponentEvent e) {
        this.repaint();
    }
	public void componentHidden(ComponentEvent e) {
    }
	public void componentShown(ComponentEvent e) {
		this.repaint();
    }
	public void focusGained(FocusEvent e) {
		this.repaint();
	}
    public void focusLost(FocusEvent e) {
    	this.repaint();
    }
    
    public class redrawIt extends TimerTask{

		@Override
		public void run() {
			repaint();
		}

		
    	
    }

	@Override
	public void dragGestureRecognized(DragGestureEvent event) {
		System.out.println("dragGestureRecognized");
		
		if(currentNode != null){
			Cursor cursor = null;
			if (event.getDragAction() == DnDConstants.ACTION_COPY) {
	            cursor = DragSource.DefaultCopyDrop;
	        }
			LibraryPreviewTransferHandler handler = (LibraryPreviewTransferHandler) libraryPane.getLibraryPreviewParentPanel().getTransferHandler();
			
			Transferable transferable = handler.createTransferable(currentNode);
			
			event.startDrag(cursor, transferable);
		}
	}
	@Override
	public void dragDropEnd(DragSourceDropEvent dsde) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void dragEnter(DragSourceDragEvent dsde) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void dragExit(DragSourceEvent dse) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void dragOver(DragSourceDragEvent dsde) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void dropActionChanged(DragSourceDragEvent dsde) {
		// TODO Auto-generated method stub
		
	}
	
	
}
